﻿namespace PowerSong.UserInterface
    {
    using System;
    using System.IO;
    using System.Text;
    using PowerSong.BibleSupport;
    using PowerSong.Indexer;
    using PowerSong.SongDatabase;
    using System.Windows;

    public static class State
        {

        #region Delegates and events

        public delegate void DatabaseLoadedDelegate(Database database, Settings settings);

        public static event DatabaseLoadedDelegate DatabaseLoaded = null;

        #endregion

        public static string AppDataLocation { get; private set; }

        public static Theatre Theatre { get; private set; }

        public static BibleIndex Bible { get; private set; }

        public static Database Database { get; private set; }

        public static Settings Settings { get; private set; }

        public static Indexer Indexer { get; private set; }

        public static Searcher Searcher { get; private set; }

        public static Song ActiveSong { get; private set; }

        public static int ActiveVerse { get; private set; }

        static State()
            {
            AppDataLocation = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Hill Research", "PowerSong 2.X");
            Theatre = new Theatre();
            if (!Directory.Exists(AppDataLocation)) Directory.CreateDirectory(AppDataLocation);
            }

        public static void CreateDatabase(string fileName)
            {

            // Close database if one it is currently open
            if (Database != null) State.CloseDatabase();

            // Set state variables
            Database = Database.Create(fileName);
            Settings = new UserInterface.Settings(Database);

            // Create a single default category for all songs
            var newCategory = new Category("All Songs", true);
            State.Database.Categories.Write(newCategory);

            // Create a single default style
            var newStyle = StyleManager.CreateDefault("PowerSong");
            Database.Styles.Write(newStyle);
            Settings.DefaultStyle = newStyle;
            Settings.SaveChanges();

            // Index the database
            RecreateIndex();

            // Raise events
            if (DatabaseLoaded != null) DatabaseLoaded(Database, Settings);

            }

        public static bool LoadDatabase(string fileName)
            {

            // Close database if one it is currently open
            if (Database != null) State.CloseDatabase();

            try
                {

                // Set database variable
                Database = Database.Load(fileName);
                Settings = new UserInterface.Settings(Database);

                // Initialise the active Bible translation
                if (Settings.ActiveBibleTranslation != null)
                    {
                    try
                        {
                        ChangeBible(Settings.ActiveBibleTranslation);
                        }
                    catch
                        {
                        Utilities.ShowErrorMessage("Bible Support", "The Bible translation '" + State.Settings.ActiveBibleTranslation + "' is no longer installed, therefore Bible support will be disabled until you select a new Bible translation via the 'PowerSong Configuration' window, accessible from the Tools menu.");
                        ChangeBible(null);
                        }
                    }

                // The database must have a default style
                if (Database.Styles.Count() <= 0)
                    {

                    // Create a new style
                    var style = StyleManager.CreateDefault("PowerSong");
                    Database.Styles.Write(style);
                    Settings.DefaultStyle = style;
                    Settings.SaveChanges();

                    }
                else if (Settings.DefaultStyle == null)
                    {

                    // Just assign a random style as the default style
                    Settings.DefaultStyle = Database.Styles.Get("Default") ??
                                            Database.Styles.Get("PowerSong") ??
                                            Database.Styles.GetAllStyles()[0];
                    Settings.SaveChanges();

                    }

                // Index the database
                RecreateIndex();

                // Raise events
                if (DatabaseLoaded != null) DatabaseLoaded(Database, Settings);
                return true;

                }
            catch (DatabaseIsLegacyExportFileException)
                {
                MessageBox.Show("The specified database is an export file created in an old version of PowerSong, which isn't compatible with this version." + Environment.NewLine + Environment.NewLine +
                                "If you wish to use the data contained within the file, then use the import functionality after opening a new or existing database.",
                                "Error Loading Database",
                                MessageBoxButton.OK,
                                MessageBoxImage.Error);
                return false;
                }

            }

        public static void ChangeSong(Song newSong)
            {
            ActiveSong = newSong;
            ActiveVerse = 0;
            }

        public static void RecreateIndex()
            {

            // Set up indexer
            Indexer = new Indexer();
            foreach (var song in Database.Songs.GetAllSongs())
                {

                // Compile the contents of the song that will be added to the index
                var contents = new StringBuilder(song.Title);
                foreach (var verseText in song.Verses)
                    {
                    contents.AppendLine().AppendLine(verseText);
                    }

                // Add the song to the index
                Indexer.AddFileContentsToIndex(song.ID.ToString(), contents.ToString());

                }

            // Set up searcher
            Searcher = new Searcher(Indexer);

            }

        public static void ChangeBible(string translationName)
            {

            // Close the currently open bible
            if (Bible != null)
                {
                Bible.Close();
                Bible = null;
                }

            // Are we simply closing the bible?
            if (translationName == null) return;

            // Is the specified bible translation installed?
            if (!BibleTranslationManager.IsTranslationInstalled(translationName))
                {
                throw new Exception("The bible translation '" + translationName + "' is not installed.");
                }

            // Switch to the new translation
            Bible = BibleTranslationManager.LoadTranslation(translationName);
            
            }

        public static void CloseDatabase()
            {

            // Write relevant activity messages to the activity log
            if (Settings.EnableReporting && State.ActiveSong != null)
                {
                State.Database.ActivityLog.Write(ActivityItemType.Song, State.ActiveSong.ID, ActivityAction.Hidden);
                }

            // Compact the database
            if (State.Database != null) State.Database.Compact();
            Database = null;
            Settings = null;
            Indexer = null;
            Searcher = null;

            }

        }

    }
